04. 系统原理
1. 数据库管理系统(DBMS)架构
1.1 DBMS核心组件 (The Components of DBMS Core)
DBMS核心是数据库系统的中枢,负责处理用户请求、管理数据存储和确保数据一致性。其主要组件协同工作,将高级的数据库语句(如SQL)转化为对底层存储的实际操作。
- 语义分析与查询处理 (Semantic Analysis and Query Treatment):
- DDL (Data Definition Language):数据定义语言,用于定义数据库结构,如创建表、索引等。
- QL (Query Language):查询语言,用于查询数据,如SELECT语句。
- DML (Data Manipulation Language):数据操作语言,用于修改数据,如INSERT、UPDATE、DELETE。
- DCL (Data Control Language):数据控制语言,用于权限管理和事务控制,如GRANT、REVOKE。
- 解析器 (Parser):将SQL语句解析成内部表示形式,通常是语法树 (Grammar Tree)。
- 授权检查 (Grant Checking):验证用户是否有执行操作的权限。
- 并发控制 (Concurrency Control):管理多个并发事务对数据库的访问,确保数据的一致性和隔离性。
- 恢复机制 (Recovery Mechanism):在系统故障(如断电、软件崩溃)后,将数据库恢复到一致状态。
- 访问管理 (Access Management):负责数据的物理存储和检索,将逻辑数据请求转化为对操作系统文件或裸设备的I/O操作。
1.2 DBMS进程结构 (The Process Structure of DBMS)
DBMS的进程结构决定了其如何处理来自应用程序的并发请求。
- 单进程结构 (Single Process Structure):
- 应用程序代码与DBMS核心编译成一个独立的
.exe
文件,作为一个单一进程运行。 - 优点:结构简单,开销小。
- 缺点:无法支持多用户并发访问,扩展性差,通常用于嵌入式或小型数据库。
- 用例:SQLite数据库,常用于移动应用或桌面应用,其数据库引擎直接嵌入到应用程序中。
- 应用程序代码与DBMS核心编译成一个独立的
- 多进程结构 (Multi Processes Structure):
- 每个应用程序进程对应一个独立的DBMS核心进程。
- 应用程序进程通过进程间通信(如管道pipe)与DBMS核心进程交互。
- 优点:进程间隔离性好,一个DBMS核心进程崩溃不会影响其他进程。
- 缺点:进程创建和切换开销大,资源消耗高。
- 用例:早期的数据库系统,如Oracle的专用服务器模式(Dedicated Server Mode),每个客户端连接都会启动一个独立的服务器进程。
- 多线程结构 (Multi Threads Structure):
- 只有一个DBMS主进程(通常称为守护进程DAEMON),每个应用程序进程通过管道/套接字与DBMS主进程通信。
- DBMS主进程为每个应用程序请求创建一个或分配一个DBMS核心线程来处理。
- 所有线程共享DBMS主进程的资源(如目录、锁表、缓冲区)。
- 优点:线程创建和切换开销小于进程,资源共享效率高,并发性好。
- 缺点:线程间共享内存,一个线程的错误可能影响整个DBMS进程。
- 用例:现代主流数据库系统(如MySQL、PostgreSQL、SQL Server、Oracle的共享服务器模式),通常采用多线程或混合(多进程+多线程)结构来提高并发处理能力。
2. 数据库访问管理 (Database Access Management)
数据库访问管理是将逻辑数据请求转化为对操作系统文件或裸设备的物理I/O操作的关键环节。文件结构和访问路径的选择直接影响数据访问速度。
2.1 访问类型 (Access Types)
不同的查询类型需要不同的访问策略。
- 查询文件中的全部或大部分记录(>15%)。
- 查询特定记录(精确匹配)。
- 查询部分记录(<15%)。
- 范围查询 (Scope Query)。
- 更新操作 (Update)。
2.2 文件组织 (File Organization)
文件组织方式决定了数据在磁盘上的物理存储布局。
- 堆文件 (Heap File):
- 记录按插入顺序存储,检索时顺序扫描。
- 特点:最基本和通用的文件组织形式。
- 适用场景:适合批量插入,不适合频繁查询特定记录。
- 直接文件 (Direct File):
- 记录地址通过哈希函数根据某个属性值映射。
- 特点:通过哈希函数直接定位记录,访问速度快。
- 适用场景:适合精确匹配查询。
- 索引文件 (Indexed File):
- 结合索引和堆文件/聚簇文件。
- 特点:通过索引快速定位记录,提高查询效率。
- 动态哈希 (Dynamic Hashing):
- 一种支持动态扩展和收缩的哈希技术。
- 特点:解决了静态哈希表大小固定、冲突处理复杂的问题。
- 网格结构文件 (Grid Structure File):
- 适用于多属性查询。
- 特点:将多维数据空间划分为网格,支持多维范围查询。
- 裸设备 (Raw Disk):
- 直接访问磁盘的物理块,绕过操作系统的文件系统缓存。
- 特点:DBMS可以更精细地控制物理I/O,提高性能,但管理复杂。
- 注意:逻辑块与物理块的区别。
2.3 索引技术 (Index Technique)
索引是提高数据检索效率的关键。
- B+树 (B+ Tree):
- 特点:广泛应用于数据库和文件系统,支持高效的范围查询和精确匹配查询,所有叶子节点通过指针连接,便于范围遍历。
- 重要性:非常重要,几乎所有关系型数据库都使用B+树作为主要索引结构。
- 聚簇索引 (Clustering Index):
- 特点:数据行的物理存储顺序与索引的逻辑顺序一致,一个表只能有一个聚簇索引。
- 优点:对于范围查询和按索引列排序的查询性能极佳,因为相关数据物理上是连续的。
- 缺点:插入和更新可能导致数据重组。
- 倒排文件 (Inverted File):
- 特点:记录某个属性值出现在哪些记录中,常用于全文检索。
- 位图索引 (Bitmap Index):
- 特点:适用于低基数(distinct值少)的列,通过位图表示数据存在性。
- 适用场景:数据仓库和OLAP(联机分析处理)系统。
3. 查询优化 (Query Optimization)
查询优化的目标是以最低的成本和最短的时间获取用户查询结果。它通过“重写”用户提交的查询语句,并选择最有效的操作方法和步骤来实现。
3.1 查询优化概述 (Summary of Query Optimization)
查询优化分为两个主要阶段:
- 代数优化 (Algebra Optimization):
- 对原始查询表达式进行一系列等价转换,将其转换为等价但更有效的执行形式。
- 核心思想:尽早过滤数据,减少中间结果集。
- 用例:将选择()操作下推到连接()操作之前,可以显著减少参与连接的数据量。
- 例如:
- 经过代数优化后,可以先对S、SP、P表进行选择操作,再进行连接,减少中间结果集的大小。
- 操作优化 (Operation Optimization):
- 决定如何具体执行代数优化后的查询计划,包括选择具体的算法(如连接算法)、访问路径(是否使用索引)等。
- 核心思想:选择成本最低的物理执行计划。
3.2 查询的等价转换 (The Equivalent Transform of a Query)
等价转换基于关系代数规则,将查询树转换为更优的执行顺序。
- 查询树 (Query Tree):
- 叶子节点:关系(表)。
- 中间节点:一元/二元操作(如选择、投影、连接)。
- 从叶子到根的顺序:操作的执行顺序。
- 关系代数等价转换规则 (The equivalent transform rules of relational algebra):
- 交换律: (笛卡尔积/连接)
- 结合律:
- 投影的簇集规则:,当 时合法。
- 选择的簇集规则:
- 选择与投影的交换规则:。
- 如果 包含不属于 的属性 ,则 。
- 选择与笛卡尔积的交换规则:
- 如果 只包含 的属性:。
- 如果 ,且 只包含 的属性, 只包含 的属性:。
- 如果 ,且 只包含 的属性, 包含 和 的属性:。
- 选择与并/差集的分配律:
- 投影与笛卡尔积的分配律:
- ,其中 是 的属性, 是 的属性, 且 。
- 投影与并集的分配律:。
- 基本原则 (Basic principles):
- 尽可能将一元操作下推:将选择()和投影()操作尽可能下推到查询树的叶子节点,以减少中间结果集的大小。
- 查找并合并公共子表达式 (Look for and combine the common sub-expression):避免重复计算。
3.3 操作优化 (The Operation Optimization)
操作优化关注如何选择具体的算法来执行查询操作。
- 连接操作优化 (Optimization of join operation):
- 嵌套循环连接 (Nested Loop Join):
- 一个关系作为外层循环(O),另一个作为内层循环(I)。对于O中的每条元组,扫描I一次以检查连接条件。
- 成本计算:对于 ,如果 作为外层, 作为内层, 是 的物理块数, 是 的物理块数,系统有 个块 缓冲区(),其中 个用于 ,一个用于 ,则总磁盘访问次数为:
- 特点:最通用的连接算法,适用于各种情况,但效率可能较低。
- 归并排序连接 (Merge Scan Join):
- 要求参与连接的关系预先在连接属性上排序。如果未排序,需要考虑排序成本。
- 特点:如果数据已排序,只需对两个关系各扫描一次,效率高。
- 使用索引或哈希查找匹配元组 (Using index or hash to look for mapping tuples):
- 在嵌套循环连接中,如果内层关系在连接属性上有合适的索引(如B+树索引),可以替代顺序扫描,显著提高效率。
- 特点:当连接属性上有聚簇索引或哈希时效果最佳。
- 哈希连接 (Hash Join):
- 将两个关系根据连接属性使用相同的哈希函数散列到哈希文件中,然后在哈希文件上进行连接。
- 特点:对于大数据集和等值连接效率很高。
- 嵌套循环连接 (Nested Loop Join):
4. 恢复 (Recovery)
恢复机制的主要作用是减少故障发生的可能性(预防)和从故障中恢复(解决),将数据库恢复到一致状态。
4.1 恢复简介 (Introduction)
- 冗余 (Redundancy):是实现恢复的必要条件,通过备份、日志等方式存储冗余信息。
- 通用方法:
- 周期性转储 (Periodical Dumping):
- 特点:简单易实现,开销低。
- 缺点:故障发生后,转储点到故障点之间的更新可能丢失。
- 变种:备份 + 增量转储 (Incremental Dumping)(只备份更新的部分)。
- 适用场景:文件系统或小型DBMS。
- 备份 + 日志 (Backup + Log):
- 日志 (Log):记录自上次备份以来数据库的所有更改。
- 记录内容:
- 更新操作:旧值 (Before Image - B.I) 和新值 (After Image - A.I)。
- 插入操作:新值 (A.I)。
- 删除操作:旧值 (B.I)。
- 恢复过程:
- Undo (撤销):对于未完成的事务,使用日志中的B.I撤销其修改。
- Redo (重做):对于已完成但结果未及时写入数据库的事务,使用日志中的A.I重做其修改。
- 特点:可以恢复数据库到最近的一致状态。
- 周期性转储 (Periodical Dumping):
4.2 事务 (Transaction)
事务是数据库管理系统执行的逻辑工作单元,具有ACID特性。
-
原子性 (Atomicity):事务是不可分割的最小工作单元,要么全部完成,要么全部不完成(Nothing or All)。
- Rollback (回滚):异常终止,撤销所有操作。
- Commit (提交):正常终止,永久保存所有操作。
-
一致性 (Consistency Preservation):事务执行前后,数据库从一个一致状态转换到另一个一致状态。
-
隔离性 (Isolation):并发事务的执行互不影响,如同串行执行一样。
-
持久性 (Durability):一旦事务成功完成(提交),其对数据库的修改是永久的,即使系统发生故障也能恢复。
-
用例:转账操作
Begin transaction
read A
A := A - s
if A < 0 then
Display "insufficient fund"
Rollback /* 撤销并终止 */
else
B := B + s
Display "transfer complete"
Commit /* 提交更新并终止 */
4.3 支持恢复的结构 (Some Structures to Support Recovery)
恢复信息(如日志)必须存储在**非易失性存储器 (nonvolatile storage)**中。
- 提交列表 (Commit List):已提交事务的事务ID (TID) 列表。
- 活动列表 (Active List):正在进行中事务的TID列表。
- 日志 (Log):记录事务ID、数据块ID、旧值、新值等信息。